
/*
 ============================================================================
 Name        : FaceDetection.c
 Author      : 
 Version     :
 Copyright   : Your copyright notice
 Description : Face Detection
 ============================================================================
 */
/*
#include "cv.h"
#include "highgui.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include <float.h>
#include <limits.h>
#include <time.h>
#include <ctype.h>


#define BS 11     // Block Size

// Create memory for calculations
static CvMemStorage* storage = 0;

// Create a new Haar classifier
static CvHaarClassifierCascade* cascade = 0;

// Create a string that contains the cascade name
const char* cascade_name = "/opt/local/share/opencv/haarcascades/haarcascade_frontalface_alt_tree.xml";
		//"/opt/local/share/opencv/haarcascades/haarcascade_frontalface_alt.xml";
		//"/opt/local/share/opencv/haarcascades/haarcascade_frontalface_alt_tree.xml";
		//"/opt/local/share/opencv/haarcascades/haarcascade_profileface.xml";


int plenght(CvPoint point_1, CvPoint point_2){

	float a=(float)abs(point_1.x-point_2.x);
	float b=(float)abs(point_1.y-point_2.y);

	if(a!=0 && b!=0){
		return (int)sqrt(pow(a,2.0)+pow(b,2.0));
	}

	return -1;
}

// Function to detect and draw any faces that is present in an image
int detect_and_draw(IplImage* img, int count) {
	int scale = 1;
	char text[60];
	int count_win_size=80;
	int tollerance=2;
	int lenght=0;
	CvFont font;
	CvScalar color_tab[2];
	color_tab[0] = CV_RGB(255,0,0);
	color_tab[1] = CV_RGB(0,255,0);

	// Create two points to represent the face locations
	CvPoint pt1, pt2;
	int i;

	storage = cvCreateMemStorage(0);
	cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 1.0, 1.0, 0, 1, CV_AA);

	// Find whether the cascade is loaded, to find the faces. If yes, then:
	if (cascade) {

		// There can be more than one face in an image. So create a growable sequence of faces.
		// Detect the objects and store them in the sequence
		CvSeq* faces = cvHaarDetectObjects(img, cascade, storage, 1.1, 2,
				CV_HAAR_DO_CANNY_PRUNING, cvSize(40, 40));

		// Loop the number of faces found.
		for (i = 0; i < (faces ? faces->total : 0); i++) {
			// Create a new rectangle for drawing the face
			CvRect* r = (CvRect*) cvGetSeqElem(faces, i);

			// Find the dimensions of the face,and scale it if necessary
			pt1.x = r->x * scale;
			pt2.x = (r->x + r->width) * scale;
			pt1.y = r->y * scale;
			pt2.y = (r->y + r->height) * scale;

			lenght=plenght(pt1, pt2);
			sprintf(text, "DR: %d\n", lenght);
			//printf(text, "DR: %d\n", plenght(pt1, pt2));
			// Draw the rectangle in the input image
			if(count_win_size-tollerance<lenght && lenght<count_win_size+tollerance){
				cvRectangle(img, pt1, pt2, color_tab[1], 3, 8, 0);
				cvPutText(img, text, cvPoint(pt1.x, pt2.y+30.0), &font, cvScalar(255, 255, 255, 0));
			}
			else{
				cvRectangle(img, pt1, pt2, color_tab[0], 3, 8, 0);
				cvPutText(img, text, cvPoint(pt1.x, pt2.y+30.0), &font, cvScalar(255, 255, 255, 0));
			}
			count++;
		}
		cvRelease((void**) &faces);
	}

	cvReleaseMemStorage(&storage);
	return count;
}

int main(void) {

	CvCapture * pCapture; //new OpenCV capture stream
	IplImage *frame, *frame_copy, *frame_flip = 0;
	int new_count=0;
	int old_count=0;
	int main_count=0;

	pCapture = cvCaptureFromCAM(0); //choose camera for capture
	cvSetCaptureProperty(pCapture,CV_CAP_PROP_FPS,15);
	cvNamedWindow("video");
	cvResizeWindow("video", 640, 480);

	//--------------------------------Cascade settings---------------------------------------

	// Load the HaarClassifierCascade
	cascade = (CvHaarClassifierCascade*) cvLoad(cascade_name, 0, 0, 0);

	// Check whether the cascade has loaded successfully. Else report and error and quit
	if (!cascade) {
		fprintf(stderr, "ERROR: Could not load classifier cascade\n");
		return -1;
	}

	// Allocate the memory storage
	storage = cvCreateMemStorage(0);

	//-----------------------------------------------------------------------------------------

	int key = -1;
	while (key == -1) {

		frame = cvQueryFrame(pCapture);

		frame_copy = cvCreateImage(cvSize(frame->width / 2.2, frame->height
				/ 2.2), frame->depth, frame->nChannels);
		frame_flip = cvCreateImage(cvSize(frame->width / 2.2, frame->height
						/ 2.2), frame->depth, frame->nChannels);
		cvResize(frame, frame_copy, CV_INTER_NN);
		cvFlip(frame_copy, frame_flip,1);
		cvReleaseImage(&frame_copy);

		old_count=new_count;
		new_count=0;
		// Call the function to detect and draw the face
		new_count=detect_and_draw(frame_flip, new_count);

		//------------------Algoritmo per contare----------------------
		//Soluzione naive basato sulle differenze dei fotogrammi
		//non funziona se il numero di persone cresce
		if(abs(new_count-old_count)==0)
			main_count=main_count;
		else if(new_count<old_count){
			main_count=main_count+abs(new_count-old_count);
		}

		//Soluzione a tempo, lo spazio di percorrenza del varco è
		//calcolato per 3 secondi, esegue la conta ogni 3 secondi.

		//Soluzione a riconoscimento facciale, in Fincantieri ogni persona
		//che entra ha memorizzata nel sistema una foto.

		cvShowImage("video", frame_flip);
		cvReleaseImage(&frame_flip);

		// Wait for a while before proceeding to the next frame
		if (cvWaitKey(10) >= 0)
			break;

	}
	// Release the images, and capture memory
	cvReleaseImage(&frame_copy);
	cvReleaseCapture(&pCapture);

	return EXIT_SUCCESS;
}


//Codice da integrare per la motion detection
/*

void main() {
    IplImage *imgA = NULL;
    IplImage *imgB = NULL;
    IplImage *grayA = NULL;
    IplImage *grayB = NULL;
    IplImage *velx = NULL;
    IplImage *vely = NULL;

    imgA = cvLoadImage("tsukuba_scene1.row3.col1.ppm", 1);
    imgB = cvLoadImage("tsukuba_scene1.row3.col2.ppm", 1);

    grayA = cvCreateImage(cvGetSize(imgA), IPL_DEPTH_8U, 1);
    grayB = cvCreateImage(cvGetSize(imgB), IPL_DEPTH_8U, 1);

    CvSize size = cvGetSize(imgA);

    velx = cvCreateImage(size, IPL_DEPTH_32F, 1);   // cvCreateImage(cvGetSize(imgA),32,1);
    vely = cvCreateImage(size, IPL_DEPTH_32F, 1);

    cvCvtColor(imgA, grayA, CV_BGR2GRAY);
    cvCvtColor(imgB, grayB, CV_BGR2GRAY);

    cvCalcOpticalFlowLK(grayB, grayA, cvSize(BS, BS), velx, vely);

    //결과 출력
    cvNamedWindow("HorFlowBM", CV_WINDOW_AUTOSIZE);
    cvShowImage("HorFlowBM", velx);
    cvNamedWindow("VerFlowBM", CV_WINDOW_AUTOSIZE);
    cvShowImage("VerFlowBM", vely);

    for (int i=0; i<imgA->height; i+=5) {
        for (int j=0; j<imgA->width; j+=5) {
            int dx = (int)cvGetReal2D(velx, i, j);
            int dy = (int)cvGetReal2D(vely, i, j);
            cvLine(imgA, cvPoint(j, i), cvPoint(j+dx, i+dy), CV_RGB(255,255,255), 1, 8, 0);
        }
    }

    cvNamedWindow("OpticalFlow", CV_WINDOW_AUTOSIZE);
    cvShowImage("OpticalFlow", imgA);
    cvWaitKey(0);
}

*/
